package org.gd.hellojavacore.patterns.objectpool;

import org.gd.hellojavacore.patterns.CreationalPattern;

/**
 <pre>

 Объектный пул (англ. object pool) — порождающий шаблон проектирования, набор инициализированных
 и готовых к использованию объектов. Когда системе требуется объект, он не создаётся, а берётся из пула.
 Когда объект больше не нужен, он не уничтожается, а возвращается в пул

 ----------------------------------------------------------------------------------------------

 Применение

 Объектный пул применяется для повышения производительности, когда создание объекта
 в начале работы и уничтожение его в конце приводит к большим затратам.
 Особенно заметно повышение производительности, когда объекты часто создаются-уничтожаются,
 но одновременно существует лишь небольшое их число

 ----------------------------------------------------------------------------------------------

 Переполнение

 Если в пуле нет ни одного свободного объекта, возможна одна из трёх стратегий:

 1. Расширение пула.
 2. Отказ в создании объекта, аварийный останов.
 3. В случае многозадачной системы, можно подождать, пока один из объектов не освободится

 ----------------------------------------------------------------------------------------------

 Примеры

 1. Информация об открытых файлах в DOS.

 2. Информация о видимых объектах во многих компьютерных играх (хорошим примером является движок Doom).
 Эта информация актуальна только в течение одного кадра; после того, как кадр выведен, список опустошается.

 3. Компьютерная игра для хранения всех объектов на карте, вместо того, чтобы использовать обычные
 механизмы распределения памяти, может завести массив такого размера, которого заведомо хватит
 на все объекты, и свободные ячейки держать в виде связного списка. Такая конструкция повышает скорость,
 уменьшает фрагментацию памяти и снижает нагрузку на сборщик мусора (если он есть).

 ----------------------------------------------------------------------------------------------

 Ловушки

 1. После того, как объект возвращён, он должен вернуться в состояние, пригодное для дальнейшего использования.
 Если объекты после возвращения в пул оказываются в неправильном или неопределённом состоянии,
 такая конструкция называется объектной клоакой (англ. object cesspool).

 2. Повторное использование объектов также может привести к утечке информации. Если в объекте есть
 секретные данные (например, номер кредитной карты), после освобождения объекта эту информацию надо затереть


 </pre>
 */
public class ObjectPool implements CreationalPattern {

    public static void main(String...a) {

    }

/*

#include <vector>

class Object
{
        // ...
};


class ObjectPool
{
        private:
                struct PoolRecord
                {
                        Object* instance;
                        bool    in_use;
                };

                std::vector<PoolRecord> m_pool;

        public:
                Object* createNewObject()
                {
                        for (size_t i = 0; i < m_pool.size(); ++i)
                        {
                                if (! m_pool[i].in_use)
                                {
                                        m_pool[i].in_use = true; // переводим объект в список используемых
                                        return m_pool[i].instance;
                                }
                        }
                        // если не нашли свободный объект, то расширяем пул
                        PoolRecord record;
                        record.instance = new Object;
                        record.in_use   = true;

                        m_pool.push_back(record);

                        return record.instance;
                }

                void deleteObject(Object* object)
                {
                        // в реальности не удаляем, а лишь помечаем, что объкт свободен
                        for (size_t i = 0; i < m_pool.size(); ++i)
                        {
                                if (m_pool[i].instance == object)
                                {
                                        m_pool[i].in_use = false;
                                        break;
                                }
                        }
                }

                virtual ~ObjectPool()
                {
                        // теперь уже "по-настоящему" удаляем объекты
                        for (size_t i = 0; i < m_pool.size(); ++i)
                                delete m_pool[i].instance;
                }
};


int main()
{
        ObjectPool pool;
        for (size_t i = 0; i < 1000; ++i)
        {
                Object* object = pool.createNewObject();
                // ...
                pool.deleteObject(object);
        }
        return 0;
}

*/

}
